package com.serviceprovider.business.module.user.controller;

//~--- non-JDK imports --------------------------------------------------------

import com.serviceprovider.business.module.admin.role.services.dao.interfaces.IRoleService;
import com.serviceprovider.business.module.admin.user.dao.interfaces.IUserDao;
import com.serviceprovider.business.module.user.model.impl.User;
import com.serviceprovider.business.module.user.validators.UserRegistrationValidator;
import com.serviceprovider.business.utility.ApplicationConfigProperties;
import com.serviceprovider.business.utility.RequestConstants;

import net.tanesha.recaptcha.ReCaptcha;
import net.tanesha.recaptcha.ReCaptchaFactory;
import net.tanesha.recaptcha.ReCaptchaImpl;
import net.tanesha.recaptcha.ReCaptchaResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.providers.encoding.PasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

//~--- JDK imports ------------------------------------------------------------

import java.util.Date;

import javax.servlet.http.HttpServletRequest;

@Controller
public class UserRegistrationController {
    @Autowired
    private ApplicationConfigProperties applicationConfigProperties;
    @Autowired
    private PasswordEncoder             passwordEncoder;
    @Autowired
    private IRoleService                roleService;
    @Autowired
    private IUserDao                    userDao;
    @Autowired
    private UserRegistrationValidator   validator;

    @RequestMapping(
        value  = RequestConstants.UserRegistrationRequests.USER_REGISTRATION,
        method = RequestMethod.GET
    )
    public ModelAndView showUserRegistrationForm() {
        ModelAndView resultView = new ModelAndView(RequestConstants.UserRegistrationRequests.VIEW_USER_REGISTRATION,
                                      "user", new User());
        ReCaptcha captcha = ReCaptchaFactory.newReCaptcha(applicationConfigProperties.getCaptchaPublicKey(),
                                applicationConfigProperties.getCaptchaPrivateKey(), false);

        resultView.getModel().put("captcha", captcha.createRecaptchaHtml(null, null));

        return resultView;
    }

    private boolean isValidCaptcha(HttpServletRequest req, String challenge, String response) {
        String        remoteAddr = req.getRemoteAddr();
        ReCaptchaImpl reCaptcha  = new ReCaptchaImpl();

        reCaptcha.setPrivateKey(applicationConfigProperties.getCaptchaPrivateKey());

        ReCaptchaResponse reCaptchaResponse = reCaptcha.checkAnswer(remoteAddr, challenge, response);
        boolean           isValidCaptcha    = reCaptchaResponse.isValid();

        return isValidCaptcha;
    }

    @RequestMapping(
        value  = RequestConstants.UserRegistrationRequests.USER_REGISTRATION,
        method = RequestMethod.POST
    )
    public ModelAndView saveUserRegistration(HttpServletRequest request,
            @RequestParam("recaptcha_challenge_field") String challenge,
            @RequestParam("recaptcha_response_field") String response, @ModelAttribute("user") User user,
            BindingResult result) {
        String       viewName = RequestConstants.UserRegistrationRequests.VIEW_USER_REGISTRATION;
        ModelAndView mav      = new ModelAndView();

        user.setRole(roleService.getRoleById(2));    // Set SP role by default
        user.setEnabled(true);
        user.setDeleted(false);
        user.setCreatedOn(new Date());
        validator.validate(user, result);

        boolean validCaptcha = isValidCaptcha(request, challenge, response);

        if (result.hasErrors() ||!validCaptcha) {
            mav = new ModelAndView(viewName, "user", user);
            mav.addObject("user", user);

            ReCaptcha captcha = ReCaptchaFactory.newReCaptcha(applicationConfigProperties.getCaptchaPublicKey(),
                                    applicationConfigProperties.getCaptchaPrivateKey(), false);

            mav.getModel().put("captcha", captcha.createRecaptchaHtml(null, null));
            mav.getModel().put("captchaError", !validCaptcha);
        } else {

            // encrypt password
            user.setPassword(passwordEncoder.encodePassword(user.getPassword(), null));
            userDao.insertUser(user);
            mav = new ModelAndView("redirect:" + RequestConstants.UserRequests.LOGIN);
        }

        return mav;
    }
}



